//
//  NSDate+BZCompare.m
//  BZFoundation
//
//  Created by 郭艺伟 on 2017/9/30.
//  Copyright © 2017年 郭艺伟. All rights reserved.
//

#import "NSDate+BZCompare.h"
#import "NSDate+BZCreated.h"

#define D_MINUTE	60
#define D_HOUR		3600
#define D_DAY		86400
#define D_WEEK		604800
#define D_YEAR		31556926

static const unsigned componentFlags = (NSYearCalendarUnit| NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekCalendarUnit |  NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekdayCalendarUnit | NSWeekdayOrdinalCalendarUnit);

@implementation NSDate (BZCompare)
- (BOOL)bz_isEqualToDateIgnoringTime:(NSDate *)aDate {
    NSDateComponents *components1 = [[NSDate bz_currentCalendar] components:componentFlags fromDate:self];
    NSDateComponents *components2 = [[NSDate bz_currentCalendar] components:componentFlags fromDate:aDate];
    return ((components1.year == components2.year) &&
            (components1.month == components2.month) &&
            (components1.day == components2.day));
}

- (BOOL)bz_isToday {
    return [self bz_isEqualToDateIgnoringTime:[NSDate date]];
}

- (BOOL)bz_isTomorrow {
    return [self bz_isEqualToDateIgnoringTime:[NSDate bz_dateTomorrow]];
}

- (BOOL)bz_isYesterday {
    return [self bz_isEqualToDateIgnoringTime:[NSDate bz_dateYesterday]];
}

- (BOOL)bz_isSameWeekAsDate:(NSDate *)aDate {
    NSDateComponents *components1 = [[NSDate bz_currentCalendar] components:componentFlags fromDate:self];
    NSDateComponents *components2 = [[NSDate bz_currentCalendar] components:componentFlags fromDate:aDate];
    
    // Must be same week. 12/31 and 1/1 will both be week "1" if they are in the same week
    if (components1.week != components2.week) {
        return NO;
    }
    
    // Must have a time interval under 1 week.
    return (ABS([self timeIntervalSinceDate:aDate]) < (NSTimeInterval)D_WEEK);
}

- (BOOL)bz_isThisWeek {
    return [self bz_isSameWeekAsDate:[NSDate date]];
}

- (BOOL)bz_isNextWeek {
    NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] + D_WEEK;
    NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval];
    return [self bz_isSameWeekAsDate:newDate];
}

- (BOOL)bz_isLastWeek {
    NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] - D_WEEK;
    NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval];
    return [self bz_isSameWeekAsDate:newDate];
}

- (BOOL)bz_isSameMonthAsDate:(NSDate *)aDate {
    NSDateComponents *components1 = [[NSDate bz_currentCalendar] components:NSYearCalendarUnit | NSMonthCalendarUnit fromDate:self];
    NSDateComponents *components2 = [[NSDate bz_currentCalendar] components:NSYearCalendarUnit | NSMonthCalendarUnit fromDate:aDate];
    return ((components1.month == components2.month) &&
            (components1.year == components2.year));
}

- (BOOL)bz_isThisMonth {
    return [self bz_isSameMonthAsDate:[NSDate date]];
}

- (BOOL)bz_isLastMonth {
    return [self bz_isSameMonthAsDate:[[NSDate date] bz_dateBySubtractingMonths:1]];
}

- (BOOL)bz_isNextMonth {
    return [self bz_isSameMonthAsDate:[[NSDate date] bz_dateByAddingMonths:1]];
}

- (BOOL)bz_isSameYearAsDate:(NSDate *)aDate {
    NSDateComponents *components1 = [[NSDate bz_currentCalendar] components:NSYearCalendarUnit fromDate:self];
    NSDateComponents *components2 = [[NSDate bz_currentCalendar] components:NSYearCalendarUnit fromDate:aDate];
    return (components1.year == components2.year);
}

- (BOOL)bz_isThisYear {
    return [self bz_isSameYearAsDate:[NSDate date]];
}

- (BOOL)bz_isNextYear {
    NSDateComponents *components1 = [[NSDate bz_currentCalendar] components:NSYearCalendarUnit fromDate:self];
    NSDateComponents *components2 = [[NSDate bz_currentCalendar] components:NSYearCalendarUnit fromDate:[NSDate date]];
    
    return (components1.year == (components2.year + 1));
}

- (BOOL)bz_isLastYear {
    NSDateComponents *components1 = [[NSDate bz_currentCalendar] components:NSYearCalendarUnit fromDate:self];
    NSDateComponents *components2 = [[NSDate bz_currentCalendar] components:NSYearCalendarUnit fromDate:[NSDate date]];
    
    return (components1.year == (components2.year - 1));
}

- (BOOL)bz_isEarlierThanDate:(NSDate *)aDate {
    return ([self compare:aDate] == NSOrderedAscending);
}

- (BOOL)bz_isLaterThanDate:(NSDate *)aDate {
    return ([self compare:aDate] == NSOrderedDescending);
}

#pragma mark - private
- (NSDate *)bz_dateByAddingMonths:(NSInteger)dMonths {
    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
    [dateComponents setMonth:dMonths];
    NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:self options:0];
    return newDate;
}

- (NSDate *)bz_dateBySubtractingMonths:(NSInteger)dMonths {
    return [self bz_dateByAddingMonths:-dMonths];
}

@end
